package gateway.mgt

import com.amihaiemil.camel.Yaml
import gateway.mgt.api.ApiConstantParam
import gateway.mgt.api.ApiDefinition
import gateway.mgt.api.ApiGroup
import gateway.mgt.api.ApiInOutParam
import gateway.mgt.api.ratelimit.RateLimitStrategy
import grails.testing.mixin.integration.Integration
import grails.transaction.*
import spock.lang.Specification

@Rollback
@Integration(applicationClass=mgtcore.Application)
class ApiDefinitionIntegrationSpec extends Specification {

    static ApiGroup apiGroupInstance = new ApiGroup(name: "default")

    static final InOutParamsPropertiesSet = [
            [
                    order    : 2, description: "Remote a request parameter",
                    type     : ApiInOutParam.Type.Integer,
                    atRequest: [scope: ApiInOutParam.Scope.Header, name: "ip2"],
                    atBackend: null
            ]
    ]

    static final SystemParamsPropertiesSet = [
    ]

    static final ConstantParamsPropertiesSet = [
            [
                    order: 1, description: "add a constant parameter",
                    type : ApiConstantParam.Type.String,
                    scope: ApiConstantParam.Scope.Header,
                    name : "op1", value: "Hello world"
            ]
    ]

    static final RateLimitStrategyPropertiesSet = [
            [name: "demo-rate-limit", apiLimit: 200L]
    ]

    def setup() {
        apiGroupInstance.save(flush: true)
    }

    def cleanup() {

    }

    void "test method 'route(Map)'"() {
        given:
        def params = [
                apiGroup: apiGroupInstance, name: "demo1", description: "demo api 1",
                request : [path: "/Service-Set-1/sampleApi1"],
                backend : [uri: "lb://Service-Set-1", path: "/sampleApi1"],
                result  : [faultContent: "error"]
        ]
        def instance = new ApiDefinition(params)
        InOutParamsPropertiesSet.each {
            it.apiDefinition = instance
            instance.addToInOutParams(it)
        }
        ConstantParamsPropertiesSet.each {
            it.apiDefinition = instance
            instance.addToConstantParams(it)
        }
        RateLimitStrategyPropertiesSet.each {
            def strategyInstance = new RateLimitStrategy(it).save()
            instance.addToRateLimitStrategies(strategyInstance)
        }

        instance.save()
        def groupBuildElements = [routes: Yaml.createYamlSequenceBuilder(), hystrix: Yaml.createYamlMappingBuilder()]

        when:
        instance.route(groupBuildElements)
        def yaml = Yaml.createYamlInput(groupBuildElements.routes.build().toString()).readYamlSequence().yamlMapping(0)

        then:
        yaml.string("id") == params.name
        yaml.string("uri") == params.backend.uri
        yaml.yamlSequence("predicates").string(0).endsWith(params.request.path)

        and:
        //constant 2 for hystrix filter and Add Predicate path to RequestHeader
        yaml.yamlSequence("filters").size() == InOutParamsPropertiesSet.size() + ConstantParamsPropertiesSet.size() + SystemParamsPropertiesSet.size() + RateLimitStrategyPropertiesSet.size() + 1
    }
}
